#include "usart0.h"
#include <avr/io.h>

RingBuffer usart0InBuffer(256);
RingBuffer usart0OutBuffer(4);

void initUSART0(uint32_t baudRate) {
// setup H/W serial port for phone (right now: Debug interface):
	uint16_t ubrr = F_CPU / (8L*baudRate) - 1;
	UBRR0H = ubrr >> 8;
	UBRR0L = ubrr;
	UCSR0A = (1 << U2X0);
	// Just now we dont use interupts!
	UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0);
	// Set frame format: 8data, 1stop
	UCSR0C = 3 << UCSZ00;
}

ISR(USART_RX_vect) {
	if (usart0InBuffer.freeSpace()) {
		usart0InBuffer.write(UDR0);
	}
}

ISR(USART_UDRE_vect) {
	if (usart0OutBuffer.available()) {
		UDR0 = usart0OutBuffer.read();
	}
}

void usart0_write(char c) {
	// If data register empty, this implies that buffer is also empty (hopefully)
	// Hope the UDRE interrupt always comes before this!
	if (UCSR0A & (1<<UDRE0)) {
	//if (!usart0OutBuffer.available()) {
		UDR0 = c;
	} else { // Write is blocking! Well caller should really have checked this.
	//	while (!usart0OutBuffer.freeSpace());
		usart0OutBuffer.write(c);
	}
}

USART0::USART0(int32_t baudRate) {
	initUSART0(baudRate);
}
